"""
Base MCPStore class
Contains core initialization logic and basic properties
"""

import logging
from typing import Dict

from mcpstore.config.json_config import MCPConfig
from mcpstore.core.configuration.unified_config import UnifiedConfigManager
from mcpstore.core.context import MCPStoreContext
from mcpstore.core.orchestrator import MCPOrchestrator

logger = logging.getLogger(__name__)


class BaseMCPStore:
    """
    MCPStore - Intelligent Agent Tool Service Store
    Base class containing core initialization and properties
    """
    
    def __init__(self, orchestrator: MCPOrchestrator, config: MCPConfig,
                 tool_record_max_file_size: int = 30, tool_record_retention_days: int = 7):
        self.orchestrator = orchestrator
        self.config = config
        self.registry = orchestrator.registry
        self.client_manager = orchestrator.client_manager

        # [FIX] Add LocalServiceManager access attribute
        self.local_service_manager = orchestrator.local_service_manager
        self.session_manager = orchestrator.session_manager
        self.logger = logging.getLogger(__name__)

        # Tool recording configuration
        self.tool_record_max_file_size = tool_record_max_file_size
        self.tool_record_retention_days = tool_record_retention_days

        # Unified configuration manager (pass instance reference)
        self._unified_config = UnifiedConfigManager(mcp_config=config)

        self._context_cache: Dict[str, MCPStoreContext] = {}
        self._store_context = self._create_store_context()

        # Data space manager (optional, only set when using data spaces)
        self._data_space_manager = None

        # [NEW] Cache manager

        # Cache manager
        from mcpstore.core.registry.cache_manager import ServiceCacheManager, CacheTransactionManager
        self.cache_manager = ServiceCacheManager(self.registry, self.orchestrator.lifecycle_manager)
        self.transaction_manager = CacheTransactionManager(self.registry)

        # Write locks: per-agent atomic write areas
        from mcpstore.core.registry.agent_locks import AgentLocks
        self.agent_locks = AgentLocks()

        # [NEW] Smart query interface
        from mcpstore.core.registry.smart_query import SmartCacheQuery
        self.query = SmartCacheQuery(self.registry)

        # [NEW] Event-driven architecture: Initialize ServiceContainer
        from mcpstore.core.infrastructure.container import ServiceContainer
        from mcpstore.core.configuration.config_processor import ConfigProcessor

        self.container = ServiceContainer(
            registry=self.registry,
            agent_locks=self.agent_locks,
            config_manager=self._unified_config,
            config_processor=ConfigProcessor,
            local_service_manager=self.local_service_manager,
            global_agent_store_id=self.client_manager.global_agent_store_id,
            enable_event_history=False  # Disable event history in production
        )

        # [UNIFIED] Point orchestrator.lifecycle_manager to container's lifecycle_manager
        try:
            self.orchestrator.lifecycle_manager = self.container.lifecycle_manager
        except Exception as e:
            logger.debug(f"Link lifecycle_manager failed: {e}")

        # Break circular dependency: pass container and context_factory to orchestrator
        # instead of letting orchestrator hold store reference (must be after container initialization)
        orchestrator.container = self.container
        orchestrator._context_factory = lambda: self.for_store()
        # Ensure sync manager can reference store for batch registration path
        try:
            orchestrator.store = self
        except Exception:
            pass

        logger.info("ServiceContainer initialized with event-driven architecture")

    def _create_store_context(self) -> MCPStoreContext:
        """Create store-level context"""
        return MCPStoreContext(self)
    
    async def cleanup(self):
        """
        Cleanup resources on shutdown.
        
        This method handles proper cleanup of Redis clients and health check tasks.
        It follows the lifecycle management rules:
        - Only close system-created Redis clients
        - Do not close user-provided Redis clients
        - Stop health check tasks gracefully
        """
        logger.info("Starting MCPStore cleanup...")
        
        # Stop health check task if running
        health_check_task = getattr(self, "_health_check_task", None)
        if health_check_task:
            try:
                await health_check_task.stop()
                logger.debug("Health check task stopped")
            except Exception as e:
                logger.warning(f"Error stopping health check task: {e}")
        
        # Close system-created Redis client (but not user-provided)
        system_redis_client = getattr(self, "_system_created_redis_client", None)
        if system_redis_client:
            try:
                await system_redis_client.close()
                logger.debug("System-created Redis client closed")
            except Exception as e:
                logger.warning(f"Error closing Redis client: {e}")
        
        # Do NOT close user-provided Redis client
        user_redis_client = getattr(self, "_user_provided_redis_client", None)
        if user_redis_client:
            logger.debug("User-provided Redis client not closed (managed by user)")
        
        logger.info("MCPStore cleanup completed")
